/**
 * @author Juntalis
 */

function Interface()
{
	return {
		Title : "",
		Body : "",
		Height : 0,
		onLoad : function() {},
		onBuild : function() {}
	}
}

function Interfaces(str)
{
	var ret = new Interface();
	switch(str) {
		/* 
		 * UserLogin
		 * The interface used to log in.
		 */
		case "UserLogin":
			ret.Title = "User Login";
			ret.Body = "<form id=\"FrmLogin\">\n" +
			"\t\t\t\t\t<strong>Username</strong>:&nbsp;&nbsp;" +
			"<input id=\"UName\" name=\"UserName\" type=\"text\" class=\"buffer\" maxlength=\"35\">\n" +
			"\t\t\t\t\t<strong>Password</strong>:&nbsp;&nbsp;" +
			"<input id=\"UPass\" name=\"UserPass\" type=\"password\" class=\"buffer\">\n" +
			"\t\t\t\t\t<p>" +
			"\n\t\t\t\t\t\t<input type=\"checkbox\" id=\"RUser\" class=\"chkbox\" name=\"RememberUser\" />" +
			"\n\t\t\t\t\t\t<strong>Remember me.</strong><br />\n" +
			"\t\t\t\t\t\t<input type=\"checkbox\" id=\"ALogin\" class=\"chkbox\" name=\"AutoLogin\" disabled=\"true\" />\n" +
			"\t\t\t\t\t\t<strong>Automatically log me in.</strong>\n" +
			"\t\t\t\t\t</p>\n" +
			"\t\t\t\t\t<button id=\"cmdSubmit\" disabled=\"true\">Login</button>\n" +
			"\t\t\t\t</form>";
			ret.Height = 220;
			ret.onLoad = function() {
				/* Checkbox Manipulation */
				$("#RUser").change(function() {
					if ($("#RUser:checked").length) {
						$("#ALogin").removeAttr("disabled");
					} else {
						$("#ALogin").removeAttr("checked").attr("disabled", "true");
					}
				});
				
				/* Button Animation and Manipulation. */
				$("button").mousedown(function() {
					if(!$(this).hasClass("enabled")) return;
					$(this).css("background", "url('img/darkbar-c.png') repeat-x").css("color", "#ccc");
				});
				$("button").mouseup(function() {
					if(!$(this).hasClass("enabled")) return;
					$(this).css("background", "url('img/darkbar-h.png') repeat-x").css("color", "#fff");
					ValidateData();
				});

				$("#FrmLogin").submit(function() {
					return false;
				});
				
				/* Textbox Manipulation */
				$("#FrmLogin > input").keyup(function() {
					if ($("#FrmLogin > input[value=]").length == 0) {
						$("#cmdSubmit")
							.removeAttr("disabled")
							.addClass("enabled")
							.attr("class","enabled");
					} else {
						$("#cmdSubmit")
							.removeClass("enabled")
							.attr("disabled", "true")
							.removeAttr("class");
					}
				});
				
				// This validates the form data, then
				// transitions the screen to the lobby
				// screen if it's ready.
				function ValidateData() {
					// Lock these until we're done.
					var blAutoDisabled = true;
					$("#UName").attr("disabled", "true");
					$("#UPass").attr("disabled", "true");
					$("#cmdSubmit").attr("disabled", "true");
					$("#RUser").attr("disabled", "true");
					if(!$("#ALogin").attr("disabled")) {
						blAutoDisabled = false;
						$("#ALogin").attr("disabled", "true");
					} 
					
					
					// Get values of the text inputs.
					var strUName = $("#UName").val();
					var strUPass = $("#UPass").val();
					
					// Begin validity checking.
					var blValid = true;
					var strInvalidWhy = "";
					
					// Check for blank fields.
					if ($("input:text[value=]").length != 0) {
						blValid = false;
						strInvalidWhy = "You must fill out both fields!";
					}
					
					// Check for invalid chars.
					if (strUName.match(/[^A-Z\d[\]-]/gi)) {
						blValid = false;
						strInvalidWhy = "Your name can only consist of letters, numbers, \"-\", \"[\", or \"]\"!";
					}
					
					
					// Check to make sure we have valid data.
					if (!blValid) {
						alert(strInvalidWhy);
						$("#UName").removeAttr("disabled");
						$("#UPass").removeAttr("disabled");
						$("#cmdSubmit").removeAttr("disabled");
						$("#RUser").removeAttr("disabled");
						if (!blAutoDisabled) $("#ALogin").removeAttr("disabled");
						return false;
					}
					
					
					// Save settings.
					if ($("#RUser:checked").length > 0) {
						Settings.User.Remember = "true";
						App.SettingsManager.SetUser(strUName, strUPass);
						if ($("#ALogin:checked").length > 0) {
							Settings.User.AutoLogin = "true";
						} else {
							Settings.User.AutoLogin = "false";
						}
					} else {
						Settings.User.Remember = "false";
						Settings.User.AutoLogin = "false";
						App.SettingsManager.SetUser("", "");
					}
					
					// Finally, save our new settings.
					App.SettingsManager.SaveSettings();
					
					// Create the bot and begin transitioning user interfaces.
					Bot.Name = strUName;
					Bot.Password = md5(strUPass);
					
					// Load the lobby interface.
					UI.Manager.LoadInterface(Interfaces("Scripting"));
				}
			};
			ret.onBuild = function() {
				// Begin checking settings.
				if (Settings.User.Remember == "true") {
					$("#UName").val(Settings.User.Name);
					$("#UPass").val(Settings.User.Password);
					$("#RUser").attr("checked", "true");
					$("#ALogin").removeAttr("disabled");
					$("#cmdSubmit")
						.removeAttr("disabled")
						.addClass("enabled");
					if (Settings.User.AutoLogin == "true") {
						$("#ALogin")
							.attr("checked", "true")
							.attr("class","enabled");
					}
				}
			};
			return ret;
			break;
			
		/* 
		 * Hub
		 * The interface used after the user has logged in.
		 */
		case "Hub":
			ret.Title = "Central Hub";
			ret.Body = "<p>Welcome, <span id=\"HubUsrName\"><strong>fag</strong></span></p>\n";
			ret.Height = 253;
			ret.onLoad = function()
			{
				$("<div />")
					.addClass("smoothwhite")
					.attr("id", "HdHub")
					.css("font-size", "1.25em")
					.css("padding", "5px")
					.html("<strong>Toribash Servers</strong> - Loading...")
					.animate(
					{
						opacity: "1.0",
						height: "20px"
					}, 400)
					.appendTo("#CtMain");
					
				$("<div />")
					.addClass("smoothwhite")
					.attr("id", "CtHub")
					.css("word-wrap", "break-word")
					.css("overflow", "auto")
					.css("text-align", "center")
					.appendTo("#CtMain")
					.animate(
						{
							opacity : "1.0",
							height: "194px"
						},
						400,
						function() {
							$(this).html("<br /><br /><br /><br /><br /><p><img src=\"img/ani-loading.gif\"></p>");
							var lb = new Lobby();
							lb.Populate(
								function() { 
									var objServers = lb.Servers();
									if (objServers.length <= 0) return;
									var arrBinds = new Array();
									var htmServers = "<ul class=\"accordion\">\n";
									for(i=0; i < objServers.length; i++ )
									{
										//$("#HdHub").html("<strong>Toribash Servers</strong> - " + i + " Total");
										htmServers += "\t<li>\n";
										htmServers += "\t\t<a href=\"#\">" + objServers[i].Name + " <span style=\"float:right;display:block;\">Players: " + objServers[i].Players + "/" + objServers[i].MaxPlayers + "</span></a>\n";
										htmServers += "\t\t<div>\n"; 
										htmServers += "\t\t\t<strong>Description</strong>: " + objServers[i].Description;
										htmServers += "<span style=\"float:right;display:block;\"><a href=\"#\" id=\"srv_" + objServers[i].Name + "\">Connect</a></span><br />\n";
										htmServers += "\t\t\t<strong>Host/Port</strong>: " +  objServers[i].IP + ":" + objServers[i].Port + "<br />\n";
										htmServers += "\t\t\t<strong><u>Players</u></strong><br />\n";
										$.each(objServers[i].Clients,function(index,value){ htmServers += "\t\t\t<span style=\"margin-left:1.5em;\">" + value + "</span><br />\n"});
										htmServers += "\t\t</div>\n";
										htmServers += "\t</li>\n";
										var tmpSrv = { ID : "#srv_" + objServers[i].Name, Name : objServers[i].Name, Host : objServers[i].IP, Port : objServers[i].Port };
										arrBinds.push(tmpSrv);
									}
									htmServers += "</ul>\n";
									$("#HdHub").html("<strong>Toribash Servers</strong> - " + objServers.length + " Total");
									$("#CtHub")
										.html("")
										.css("text-align", "left")
										.append(htmServers);
									$('ul.accordion').accordion();
									$.each(arrBinds, function(iIndex, objVal) {
										$(objVal.ID).click(function() {
											Bot.Server.Name = objVal.Name;
											Bot.Server.Host = objVal.Host;
											Bot.Server.Port = objVal.Port;
											UI.RemoveLink($.data(document.body, "_hub_href_login"));
											UI.Manager.LoadInterface(Interfaces("ChatBox"));
										});
									});
									$("#HdHub").prepend("<input type=\"text\" class=\"buffer\" id=\"TxtJoin\" style=\"float:right;display:block;width:200px\">");
									if(Settings.App.RecentServer)
										$("#TxtJoin").css("color","#444").val(Settings.App.RecentServer);
									else 
										$("#TxtJoin").css("color","#aaa").val("Enter server name..");
									
									$("#TxtJoin")
										.css("margin","0")
										.css("padding","2px")
										.css("font-size","1em")
										.css("height","1em")
										.keyup(function(e) {
											$(this).val($(this).val().replace(" ",""));
											if (e.keyCode == 13) {
												if ($(this).val()!="") {
													var sInput = $(this).val();
													$(this).val("");
													lb.Server(sInput,
														function(sname,shost,iport)
														{
															Settings.App.RecentServer = sname.replace('"','').replace("'","");
															Bot.Server.Name = sname;
															Bot.Server.Host = shost;
															Bot.Server.Port = iport;
															UI.RemoveLink($.data(document.body, "_hub_href_login"));
															UI.Manager.LoadInterface(Interfaces("ChatBox"));
														}
													);
												}
											}
										})
										.focusin(function(e){ if($(this).val()=="Enter server name..") $(this).val("").css("color","#444"); })
										.focusout(function(e){ if($(this).val()=="") $(this).val("Enter server name..").css("color","#aaa"); });
								}
							);
						}
					);
					
			};
			ret.onBuild = function()
			{
				var hrefLogin = UI.AddLink("#", "Return to Login");
				$("#" + hrefLogin).click(
					function() {
						UI.RemoveLink($(this).attr("id"));
						UI.Manager.LoadInterface(Interfaces("UserLogin"));		
					}
				);
				$("#HubUsrName").html("<strong>" + Bot.Name + "</strong>");
				$.data(document.body, "_hub_href_login", hrefLogin);
			};
			return ret;
			break;
			
		/* 
		 * ChatBox
		 * The interface used when the bot is in-game.
		 */
		case "ChatBox":
			ret.Title = "Connecting...";
			ret.Body = "\t<div id=\"LstUsr\" class=\"buffer\" style=\"width:199px;height: 196px; float: right; margin-bottom: 0px; margin-top: 0px;\">" +
			"\t\t<strong>Loading..</strong>" +
			"</div>\n" +
			"\t<div id=\"TxtIn\" class=\"buffer\" style=\"margin-bottom: 0px; width:480px\"></div>\n" +
			"\t<input id=\"TxtOut\" type=\"text\" class=\"buffer\" maxlength=\"255\">\n";
			ret.Height = 253;
			ret.onLoad = function() {
				var sRecvBuffer = "";
				function PingTimer() {
					Bot.Send("PING");
					Misc.StartTimer(PingTimer, 5000);
				}
				
				Bot.SckClient.handleConnection(
					function(event) {
						$("#TxtOut").removeAttr("disabled");
						UI.Manager.ChangeTitle(Bot.Server.Name + " - Connected");
						Misc.StartTimer(PingTimer, 5000);
						if (Bot.Scripted.Connect != null)
							Bot.Scripted.Connect();
							
					}
				);
				
				Bot.SckClient.handleReceives(
					function(event) {
						sRecvBuffer += Bot.SckClient.recv();
						if(!sRecvBuffer) return;
						
						var data = "";
						if (sRecvBuffer.charAt(sRecvBuffer.length - 1) != '\n')
						{
							data = sRecvBuffer.substr(0, sRecvBuffer.lastIndexOf("\n"));
							sRecvBuffer = sRecvBuffer.substr(data.length - sRecvBuffer.length + 1);
						} else {
							data = sRecvBuffer.substr(0, sRecvBuffer.length - 1);
							sRecvBuffer = "";
						}
						
						// Check data
						if ((!data)||(data.length<=0))
							return;
						
						// Break up data
						var arrRecvs = data.split("\n");
						
						$.each(arrRecvs, function(index,value){
							if(value.match(/^TORIBASH 30$/)) {
								Bot.Send("mlogin " + Bot.Name + " " + Bot.Password);
								Bot.Send("SPEC");
							} else if(value.match(/^SAY\ (\d*?);(.*?)$/)) {
								var rgXp = /^SAY (\d*?);(.*?)$/;
								var sParam = rgXp.exec(value);
								if (sParam != null)
									_evSAY(sParam[1],sParam[2]);
							//} else if(value.match()) {
								
							//} else if(value.match()) {
								
							}
						});
					}
				);
				
				// Called on a SAY event.
				function _evSAY(id, data)
				{
					if(id == "0") {
						ChatBox.WriteLine("[b]Server[/b]: " + data);
						if(Bot.Scripted.ServerMessage != null)
							Bot.Scripted.ServerMessage(data);
					} else {
						var usr = new User();
						var msg = "";
						usr.ID = parseInt(id);
						
						var rgXp = /^([A-Z\[\]\d_-]*?):\ (.*?)$/i;						
						var sParam = rgXp.exec(data);
						if (sParam != null) {
							var objName = Toribash.ParseNameStr(sParam[1]);
							if(objName != null) {
								usr.Name = objName.Name;
								usr.Clan = objName.Clan;
								usr.PreClan = objName.PreClan;
							} else { usr.Name = sParam[1]; }
							msg = sParam[2];
						} else {
							rgXp = /^\^(?:\d{1,2})<\^(?:\d{1,2})([A-Z\[\]\d_\-]*?)\^(?:\d{1,2})>\ (.*?)$/i;
							sParam = rgXp.exec(data);
							if (sParam != null) {
								var objName = Toribash.ParseNameStr(sParam[1]);
								if(objName != null) {
									usr.Name = objName.Name;
									usr.Clan = objName.Clan;
									usr.PreClan = objName.PreClan;
								} else { usr.Name = sParam[1]; }
								msg = sParam[2];
							}
						}

						ChatBox.WriteLine("[b]" + usr.WholeName() + "[/b]: " + msg);
						if(Bot.Scripted.UserSay != null) Bot.Scripted.UserSay(usr, msg);
					}
				}
				
				// The text input callback.
				$("#TxtOut").keyup(
					function(e) {
						if (e.keyCode == 13) {
							if ($(this).val()!="") {
								var sInput = $(this).val();
								$(this).val("");
								Bot.Say(sInput);
							}
						}
					}
				);
				
				// Connect
				$("#TxtIn").append("<strong>Connecting to " + Bot.Server.Host + ":" + Bot.Server.Port + "</strong>");
				Bot.Connect(Bot.Server.Host, Bot.Server.Port);
			};
			ret.onBuild = function() {
				$("#TxtIn").animate({height: "200px"},400, function(){$(this).css("overflow", "auto").css("word-wrap", "break-word");});
				$("#TxtOut").width("698px").css("margin-bottom", "2px").css("margin-top","5px").attr("disabled", "true");
				$.data(document.body, "_chatbox_href_hub", UI.AddLink("#", "Return to Hub"));
				$("#" + $.data(document.body, "_chatbox_href_hub")).click(
					function() {
						UI.RemoveLink($(this).attr("id"));
						Bot.Disconnect();
						UI.Manager.LoadInterface(Interfaces("Hub"));		
					}
				);
			};
			break;
			
		/* 
		 * Scripting
		 * The interface used when to configure the script for this bot.
		 */
		case "Scripting":
			ret.Title = "Bot Scripting";
			ret.Body = "<div id=\"CtDesc\" style=\"font-size:1.25em;\">"+
			"\t<p>\n"+
			"\t\t<strong>TB-&gt;HTML</strong> gives your the ability to create your own bots to run atop this framework.\n"+
			"\t</p>\n"+
			"\t<input id=\"TxtFilePath\" type=\"text\" style=\"border:1px solid #ccc; width:702px; display:block; padding:4px;background-color:#fff;color:#444;margin-right:0px;font-size:0.8em;\" readonly=\"true\">"+
			"\t<div id=\"TxtSrc\" class=\"buffer\" style=\"padding: 0; opacity: 0.0; margin-top: 5px; margin-bottom: 5px; height: 155px;\"></div>\n"+
			"\t<button style=\"float: right; font-weight: bold; font-size: 0.8em; width: 175px;\" class=\"enabled\" id=\"CmdNext\">Continue to Lobby</button>\n"+
			"\t<button style=\"float: left; font-weight: bold; font-size: 0.8em; width: 140px;\" class=\"enabled\" id=\"CmdLoad\">Select File</button>\n"+
			"\t<button style=\"margin-left: 5px; float: left; font-weight: bold; font-size: 0.8em; width: 160px; opacity: 0.0; display: none;\" class=\"enabled\" id=\"CmdRestart\">Initialize Script</button>\n"+
			"\t<button style=\"margin-left: 5px; float: left; font-weight: bold; font-size: 0.8em; width: 140px; opacity: 0.0; display: none;\" class=\"enabled\" id=\"CmdDeselect\">Deselect File</button>\n"+
			"</div>";
			ret.Height = 250;
			ret.onLoad = function () {
				/* Settings loading */
				var fhScript; var sBotScript = "";
				if (typeof(_UserBotInit) != "undefined") {
					fhScript = air.File.applicationDirectory.resolvePath("user").resolvePath("User.Bot.js");
					var evParams = new air.Event("hideRestart");
					AnimateInterface(evParams);
				} else {
					if (Settings.App.RecentBot) {
						fhScript = new air.File();
						fhScript.nativePath = Settings.App.RecentBot;
					} else fhScript = air.File.userDirectory;
					$("#TxtFilePath").val("No script loaded..");
				}
				/* Button Animation and Manipulation. */
				$("button").mousedown(function() {
					if(!$(this).hasClass("enabled")) return;
					$(this).css("background", "url('img/darkbar-c.png') repeat-x").css("color", "#ccc");
				});
				$("button").mouseup(function() {
					if(!$(this).hasClass("enabled")) return;
					$(this).css("background", "url('img/darkbar-h.png') repeat-x").css("color", "#fff");
				});
				$("button").hover(function() {
					if(!$(this).hasClass("enabled")) return;
					$(this).css("background", "url('img/darkbar-h.png') repeat-x").css("color", "#fff");
				},function() {
					if(!$(this).hasClass("enabled")) return;
					$(this).css("background", "url('img/darkbar.png') repeat-x").css("color", "#bbb");
				});
				
				/* Next Interface Button */
				$("#CmdNext").click(function(){
					UI.RemoveLink($.data(document.body, "_script_href_login"));
					UI.Manager.LoadInterface(Interfaces("Hub"));
				});
				
				/* Load file button */
				$("#CmdLoad").click(function(){
					if($(this).attr("disabled")) return;
					var jsBotFilter = new air.FileFilter("JavaScript Toribash Bot (*.jstb)", "*.jstb"); 	
					fhScript.browseForOpen("Open", [jsBotFilter]);
					fhScript.addEventListener(air.Event.SELECT, AnimateInterface);
				});
				
				/* Animates the loading of a script file. */
				function AnimateInterface(event) {
					if(fhScript.nativePath) {
						if (fhScript.exists) {
							$("#TxtFilePath").val(fhScript.nativePath);
							$("button").each(function(i, el) {$(this).attr("disabled", "true");});
							$("#CmdDeselect")
								.css("display", "block")
								.animate({opacity: 1.0}, 400);
							if (event.type != "hideRestart") {
								$("#CmdRestart").css("display", "block").animate({opacity: 1.0}, 400);
							}
							$("#TxtSrc")
								.html("<br /><br /><p style=\"text-align:center;\"><img src=\"img/ani-loading.gif\"></p>")
								.animate({opacity: 1.0}, 400,
									function() {
										LoadScriptFile(true,null);
									}
								);
						} else {
							if (Settings.App.RecentBot) {
								fhScript = new air.File();
								fhScript.nativePath = Settings.App.RecentBot;
							} else fhScript = air.File.userDirectory;
							$("#TxtFilePath").val("No script loaded..");
						}
					}
				}
				
				/* Load Script File */
				function LoadScriptFile(blAutoDeselect, cbAfter) {
					stFile = new air.FileStream();
					try
					{
						$("button").each(function(i, el) {$(this).removeAttr("disabled");});
					    stFile.open(fhScript, air.FileMode.READ);
					    var strBuffer = stFile.readUTFBytes(stFile.bytesAvailable);
					    stFile.close();
						sBotScript = strBuffer;
					}
					catch(error)
					{
					    alert("Error while reading script file!\nError: " + error);
						if (blAutoDeselect) $("#CmdDeselect").click();
					}
					
					// Animate transition.
					$("#TxtSrc").children().animate({opacity:0.0},200,
						function(){
							$("#TxtSrc")
								.css("padding","0px")
								.html("<pre class=\"sh_javascript_dom\" style=\"margin:0;padding:3px;\">" + strBuffer.EscapeHtml() + "</pre>");
							sh_highlightDocument();
							$(this).animate({opacity:0.0},200,
								function(){
									$("button").each(function(i,el){$(this).removeAttr("disabled");});
									if(Settings.App.RecentBot)
										fhScript.nativePath = Settings.App.RecentBot;
									else
										Settings.App.RecentBot = fhScript.nativePath;
									if (cbAfter&&sBotScript) cbAfter();
								}
							);
						}
					);
				}
				
				/* Try writing a new .js file and exiting the program. */
				$("#CmdRestart").click(function(){
					$("button").each(function(i, el) {$(this).attr("disabled", "true");});
					LoadScriptFile(false,function(){
						// Create file objects.
						var stFile = new air.FileStream();
						var appBotJs =  fhScript.parent.resolvePath("User.Bot.js");
						var appInstallDir = air.File.applicationDirectory.resolvePath("user");
						
						// Write new script file.
						try {						
							stFile.open(appBotJs, air.FileMode.WRITE);
							stFile.writeUTFBytes("function _UserBotInit() { Bot.Scripted = " + sBotScript + "; }");
							stFile.close();			
						} catch(error) {
						    alert("Error while writing user bot script!\n" + error);
							if(_DEBUG.FILE) console.log(error);
							return;
						}
						
						// If native process is supported, automate the user bot installation.
						if (air.NativeProcess.isSupported) {
							try {
								// Create temporary shell script.
								var osSystem = air.Capabilities.os;
								var tmpShellScript = air.File.createTempFile();
								var tmpShScrExec = new air.File();
								var tmpShScrStartInfo = new air.NativeProcessStartupInfo();
								var tmpShScrArgs = new air.Vector["<String>"]();
								var tmpProc = new air.NativeProcess();
								var tmpShScrContents = "";
								
								// Create file according to operating system.
								if (osSystem.match(/Windows/mi)) {
									// Windows
									tmpShellScript.nativePath = tmpShellScript.nativePath + ".bat";
									tmpShScrContents = "@ECHO OFF\n"+
									"MOVE /Y \"" + appBotJs.nativePath + "\" \"" + appInstallDir.nativePath + "\"";
									tmpShScrExec.nativePath = "C:\\Windows\\system32\\cmd.exe";
									tmpShScrArgs.push("/C");
									tmpShScrArgs.push(tmpShellScript.nativePath);
								} else if ((osSystem.match(/Mac OS/mi))||(osSystem.match(/Linux/mi))) {
									// Mac OS X and Linux both use unix-style shell scripts.
									tmpShellScript.nativePath = tmpShellScript.nativePath + ".sh";
									tmpShScrContents = "#!/bin/bash\n"+
									"mv -f \"" + appBotJs.nativePath + "\" \"" + appInstallDir.nativePath + "\"";
									tmpShScrExec.nativePath = "/bin/sh";
									tmpShScrArgs.push(tmpShellScript.nativePath);
									
								} else {
									// Not sure. So instead we'll do what we would've if the
									// system couldn't do native processes.
									alert("Your operating system was not recognized.\n\nIt seems you will need to install the script manually.\n\n"+
									 "To do so, move the newly generated User.Bot.js which is in the same directory as your bot script to the 'user' subfolder located in the installation folder for this application.\n\n"+
									 "It should be located at:\n" + appInstallDir.nativePath);
									appBotJs = appBotJs.parent;
									appBotJs.openWithDefaultApplication();
									App.Exit();
									return;
								}
								
								// Use the os's line breaks.
								tmpShScrContents = tmpShScrContents.replace(/\n/g, air.File.lineEnding);
								stFile.open(tmpShellScript, air.FileMode.WRITE);
								stFile.writeUTFBytes(tmpShScrContents);
								stFile.close();
								
								// Launch application
					            tmpShScrStartInfo.executable = tmpShScrExec;
					            tmpShScrStartInfo.arguments = tmpShScrArgs;
					            tmpProc.start(tmpShScrStartInfo);
					            tmpProc.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA,
									function(event) { if(_TRACE.PROCESS) trace("Got: ", tmpProc.standardOutput.readUTFBytes(tmpProc.standardOutput.bytesAvailable)); }
								);
					            tmpProc.addEventListener(air.ProgressEvent.STANDARD_ERROR_DATA,
									function(event) { if(_TRACE.PROCESS) trace("ERROR -", tmpProc.standardError.readUTFBytes(tmpProc.standardError.bytesAvailable)); }
								);
					            tmpProc.addEventListener(air.NativeProcessExitEvent.EXIT,
									function(event) {
										 if(_TRACE.PROCESS) trace("Process exited with ", event.exitCode); 
										 
										// Finished, now we do our last acts.
										alert("To complete the installation of your bot script, you must restart the application.\nWe will now close the application.");
										if (tmpShellScript.exists) tmpShellScript.deleteFile();
										App.Exit();
									}
								);
					            tmpProc.addEventListener(air.IOErrorEvent.STANDARD_OUTPUT_IO_ERROR,
									function(event) { if(_TRACE.PROCESS) trace(event.toString()); }
								);
					            tmpProc.addEventListener(air.IOErrorEvent.STANDARD_ERROR_IO_ERROR,
									function(event) { if(_TRACE.PROCESS) trace(event.toString()); }
								);								
							} catch (error) {
								if(_DEBUG.PROCESS) console.log(error);
								if (tmpShellScript.exists) tmpShellScript.deleteFile();
								alert("There was an error while automating the installation process. It seems you will need to install the script manually.\n\n"+
								 "To do so, move the newly generated User.Bot.js which is in the same directory as your bot script to the 'user' subfolder located in the installation folder for this application.\n\n"+
								 "It should be located at:\n" + appInstallDir.nativePath + "\n\nError Details\n" + error);
								appBotJs = appBotJs.parent;
								//appBotJs.openWithDefaultApplication();
								//App.Exit();	
							}
						} else {
							 alert("It seems you will need to install the script manually.\n\n"+
							 "To do so, move the newly generated User.Bot.js which is in the same directory as your bot script to the 'user' subfolder located in the installation folder for this application.\n\n"+
							 "It should be located at:\n" + appInstallDir.nativePath);
							appBotJs = appBotJs.parent;
							appBotJs.openWithDefaultApplication();
							App.Exit();	
						}
					});
				});
				
				/* Deselect a file */
				$("#CmdDeselect").click(function(){
					$("#TxtFilePath").val("No script loaded..");
					$("button").each(function(i,el){ $(this).attr("disabled","true"); });
					$("#CmdDeselect").animate({opacity:0.0},400,function(){$(this).css("display","none");});
					$("#CmdRestart").animate({opacity:0.0},400,function(){$(this).css("display","none");});
					$("#TxtSrc").animate({opacity:0.0},400,
						function(){
							// Set Bot.Scripted to default.
							_resetBotScript();
							
							// Create file objects.
							var stFile = new air.FileStream();
							var appBotJs =  fhScript.parent.resolvePath("User.Bot.js");
							var appInstallDir = air.File.applicationDirectory.resolvePath("user");
							
							// Write new script file.
							try {						
								stFile.open(appBotJs, air.FileMode.WRITE);
								stFile.writeUTFBytes("\n");
								stFile.close();			
							} catch(error) {
							    alert("Error while writing blank file!\n" + error);
								if(_DEBUG.FILE) console.log(error);
								// Enable buttons
								$("button").each(function(i,el){$(this).removeAttr("disabled");});
								return;
							}
							
							// If native process is supported, automate the user bot installation.
							if (air.NativeProcess.isSupported) {
								try {
									// Create temporary shell script.
									var osSystem = air.Capabilities.os;
									var tmpShellScript = air.File.createTempFile();
									var tmpShScrExec = new air.File();
									var tmpShScrStartInfo = new air.NativeProcessStartupInfo();
									var tmpShScrArgs = new air.Vector["<String>"]();
									var tmpProc = new air.NativeProcess();
									var tmpShScrContents = "";
									
									// Create file according to operating system.
									if (osSystem.match(/Windows/mi)) {
										// Windows
										tmpShellScript.nativePath = tmpShellScript.nativePath + ".bat";
										tmpShScrContents = "@ECHO OFF\n"+
										"MOVE /Y \"" + appBotJs.nativePath + "\" \"" + appInstallDir.nativePath + "\"";
										tmpShScrExec.nativePath = "C:\\Windows\\system32\\cmd.exe";
										tmpShScrArgs.push("/C");
										tmpShScrArgs.push(tmpShellScript.nativePath);
									} else if ((osSystem.match(/Mac OS/mi))||(osSystem.match(/Linux/mi))) {
										// Mac OS X and Linux both use unix-style shell scripts.
										tmpShellScript.nativePath = tmpShellScript.nativePath + ".sh";
										tmpShScrContents = "#!/bin/bash\n"+
										"mv -f \"" + appBotJs.nativePath + "\" \"" + appInstallDir.nativePath + "\"";
										tmpShScrExec.nativePath = "/bin/sh";
										tmpShScrArgs.push(tmpShellScript.nativePath);
										
									} else {
										// Not sure. So instead we'll do what we would've if the
										// system couldn't do native processes.
										alert("To make sure the bot doesn't load next time, please clear the contents of your user/User.Bot.js file.\n\nShould be located at:\n" + appInstallDir.nativePath);
										if(appBotJs.exists) appBotJs.deleteFile();
										$("button").each(function(i,el){$(this).removeAttr("disabled");});
										return;
									}
									
									// Use the os's line breaks.
									tmpShScrContents = tmpShScrContents.replace(/\n/g, air.File.lineEnding);
									stFile.open(tmpShellScript, air.FileMode.WRITE);
									stFile.writeUTFBytes(tmpShScrContents);
									stFile.close();
									
									// Launch application
						            tmpShScrStartInfo.executable = tmpShScrExec;
						            tmpShScrStartInfo.arguments = tmpShScrArgs;
						            tmpProc.start(tmpShScrStartInfo);
						            tmpProc.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA,
										function(event) { if(_TRACE.PROCESS) trace("Got: ", tmpProc.standardOutput.readUTFBytes(tmpProc.standardOutput.bytesAvailable)); }
									);
						            tmpProc.addEventListener(air.ProgressEvent.STANDARD_ERROR_DATA,
										function(event) { if(_TRACE.PROCESS) trace("ERROR -", tmpProc.standardError.readUTFBytes(tmpProc.standardError.bytesAvailable)); }
									);
						            tmpProc.addEventListener(air.NativeProcessExitEvent.EXIT,
										function(event) {
											 if(_TRACE.PROCESS) trace("Process exited with ", event.exitCode); 
											// Finished, now we do our last acts.
											if (tmpShellScript.exists) tmpShellScript.deleteFile();
											// Enable buttons
											$("button").each(function(i,el){$(this).removeAttr("disabled");});
										}
									);
						            tmpProc.addEventListener(air.IOErrorEvent.STANDARD_OUTPUT_IO_ERROR,
										function(event) { if(_TRACE.PROCESS) trace(event.toString()); }
									);
						            tmpProc.addEventListener(air.IOErrorEvent.STANDARD_ERROR_IO_ERROR,
										function(event) { if(_TRACE.PROCESS) trace(event.toString()); }
									);								
								} catch (error) {
									if(_DEBUG.PROCESS) console.log(error);
									if (tmpShellScript.exists) tmpShellScript.deleteFile();
									alert("There was an error while automating the removal process. To make sure the bot doesn't load next time, please clear the contents of your user/User.Bot.js file.\n\nError Details\n" + error);
									if(appBotJs.exists) appBotJs.deleteFile();
									// Enable buttons
									$("button").each(function(i,el){$(this).removeAttr("disabled");});
								}
							} else {
								alert("To make sure the bot doesn't load next time, please clear the contents of your user/User.Bot.js file.\n\nShould be located at:\n" + appInstallDir.nativePath);
								if(appBotJs.exists) appBotJs.deleteFile();
								$("button").each(function(i,el){$(this).removeAttr("disabled");});
							}
						}
					);
				});
				
			};
			ret.onBuild = function () {
				$("#TxtSrc")
					.css("overflow","auto")
					.css("word-wrap", "break-word");
				$.data(document.body, "_script_href_login", UI.AddLink("#", "Return to Login"));
				$("#" + $.data(document.body, "_script_href_login")).click(
					function() {
						UI.RemoveLink($(this).attr("id"));
						Bot.Disconnect();
						UI.Manager.LoadInterface(Interfaces("UserLogin"));		
					}
				);
			};
			break;
		default:
			break;
	}
	return ret;
}
